/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.ban.news.server.check.checkers;

import cn.ac.iie.di.ban.news.server.check.CheckResult;
import cn.ac.iie.di.ban.news.server.check.Checker;
import java.util.HashSet;

/**
 *
 * @author zwlin
 */
public class Base64Checker implements Checker<String, String> {

    private static final HashSet<Character> BASE64_CHARS;

    static {
        BASE64_CHARS = new HashSet<>();
        for (int i = 0; i < 26; ++i) {
            BASE64_CHARS.add((char) ('A' + i));
            BASE64_CHARS.add((char) ('a' + i));
        }
        for (int i = 0; i < 10; ++i) {
            BASE64_CHARS.add((char) ('0' + i));
        }
        BASE64_CHARS.add('+');
        BASE64_CHARS.add('/');
    }

    /**
     *
     * @param src base64 string
     * @param target not used
     * @return
     */
    @Override
    public CheckResult check(String src, String target) {
        //empty
        if (null == src || (src = src.trim()).isEmpty()) {
            return new CheckResult();
        }
        char[] cs = src.toCharArray();
        //length divided by 4
        int num = cs.length % 4;
        if (num != 0) {
            return new CheckResult("Base64 check error. length cannot be divided by 4.");
        }
        //'=' in the end.
        num = cs.length - 1;
        for (int i = 0; i < 2; ++i, --num) {
            if ('=' == cs[num]) {
            } else {
                break;
            }
        }
        //num of regular base 64 chars
        while (num >= 0) {
            if (!BASE64_CHARS.contains(cs[num])) {
                return new CheckResult("Base64 check error. the " + (num + 1) + "th char is not Base64.");
            }
            --num;
        }
        return new CheckResult();
    }

}
